<!--
* 使用步骤
* 1.引入组件
* 2.使用组件
* import BsDictComponent from '@/components/select-tree'
* <select-tree v-model="" show-checkbox  @change=""change" clearable ></select-tree>
* url 请求路径
* params 请求参数
* result 方回结果data中的字段名
* initValue：初始值 单选为String,复选为Array
* show-checkbox：开启复选
* clearable： 显示清除按钮
* change(data) data为选中结果
* defaultProps指定 label ,value
例子：
      <select-tree
        v-model="dataForm.ownershipUnit"
        placeholder="权属单位"
        :initValue="dataForm.ownershipUnitCode"
        @change="changeOwnershipUnit"
        clearable
      ></select-tree>
事件：
    changeOwnershipUnit(data) {
      this.dataForm.ownershipUnitName = data.managementName;
      this.dataForm.ownershipUnitCode = data.managementCode;
    },
-->
<template>
  <div class="select-tree">
    <el-select
      ref="selectTree"
      v-bind="$attrs"
      v-on="$listeners"
      v-model="checkedOptVal"
      popper-class="customStyle"
      @clear="clearHandler"
    >
      <el-option
        :label="checkedOptVal[defaultProps.label]"
        :value="checkedOptVal[defaultProps.value]"
      >
        <el-tree
          ref="elTree"
          v-bind="$attrs"
          v-on="$listeners"
          :data="treedata"
          :props="defaultProps"
          :default-expand-all="true"
          :expand-on-click-node="false"
          :check-strictly="checkStrictly"
          :node-key="defaultProps.value"
          @node-click="handleNodeClick"
          @check="check"
        ></el-tree>
      </el-option>
    </el-select>
  </div>
</template>

<script>
import { treeDataTranslate } from '@/utils';

export default {
  name: 'SelectTree',
  data: function () {
    return {
      checkStrictly: true,
      list: [],
      treedata: [], // 显示的数据
    };
  },
  model: {
    prop: 'selectedVal',
    event: 'select',
  },
  props: {
    selectedVal: {
      type: [String, Number, Array, Object],
    },
    url: {
      type: String,
      default: '/sys/syscompany/bbtreelist',
    },
    params: {
      type: Object,
    },
    result: {
      type: String,
      default: 'pageAll',
    },
    initValue: {
      type: [String, Number, Array, Object],
    },
    defaultProps: {
      type: Object,
      default: function () {
        return {
          children: 'children',
          label: 'managementName',
          value: 'managementCode',
        };
      },
    },
  },
  computed: {
    // 读取和设置, 计算属性的 getter 和 setter
    checkedOptVal: {
      get: function () {
        return this.selectedVal || {};
      },
      set: function () {},
    },
  },
  mounted: function () {
    this.sendRequest();
  },
  methods: {
    render: function () {
      if (!this.$attrs.disabled) {
        this.$emit('click');
      }
    },
    sendRequest: function () {
      console.log('url=' + this.url);
      this.$http({
        url: this.$http.adornUrl(this.url),
        method: 'get',
        params: this.$http.adornParams({ ...this.params }),
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.list = data[this.result];
          this.treedata = treeDataTranslate(data[this.result], 'id', 'parentId');

          console.log('typeProps' + this.defaultProps);
          setTimeout(() => {
            this.renderInitVal();
          }, 500);
        }
      });
    },
    renderInitVal: function () {
      var vm = this;

      console.log('select - Tree');
      console.log(this.$attrs);
      console.log(this.$listeners);
      if (vm.initValue) {
        // 前提：开启“复选框”模式
        if (vm.$refs.elTree.showCheckbox) {
          vm.$emit('select', '当前选中' + vm.initValue.length + '个节点');
          vm.initValue.forEach((key) => {
            // 设置复选框的勾选状态
            vm.$refs.elTree.setChecked(key, true);
          });
        } else {
          vm.list.forEach((obj) => {
            if (vm.initValue === obj[vm.defaultProps.value]) {
              this.$emit('select', obj);
            }
          });
        }
      }
    },
    clearHandler: function () {
      this.$emit('select', '');
      // this.checkedOptVal = '';
      // 清除el-tree的已选中节点（的样式）
      this.$refs.elTree.setCurrentKey(null);

      // 开启“复选框”模式
      if (this.$refs.elTree.showCheckbox) {
        var checkNodes = this.$refs.elTree.getCheckedNodes();
        if (checkNodes.length > 0) {
          checkNodes.forEach((item) => {
            // 取消复选框的勾选状态
            this.$refs.elTree.setChecked(item.id, false);
          });
        }
      }
    },
    // 节点被点击时的回调
    // NOTE 点击复选框时，并不能触发下面的方法
    handleNodeClick: function (data) {
      // 前提：未开启“复选框”模式
      if (!this.$refs.elTree.showCheckbox) {
        this.checkedOptVal = data;
        // 使 input 失去焦点，并隐藏下拉框
        this.$refs.selectTree.blur();
        this.$emit('select', data);
        // debugger;
        this.$emit('change', data);
      }

      // NOTE handleNodeClick方法不处理开启了“复选框”的节点点击事件
      // NOTE check方法处理开启了“复选框”的节点点击事件，但是并没有返回选中节点的keys
      // getCheckedKeys会返回选中节点的keys
      // 因此，对于未开启复选框的下拉树直接通过v-model获取选中节点的key
      // 对于开启了复选框的下拉树需要额外调用getCheckedKeys方法获取选中节点的keys
    },
    // 当【复选框】被点击的时候触发
    check: function (data) {
      var checkKeys = this.$refs.elTree.getCheckedKeys();
      const currNode = this.$refs.elTree.getNode(data);

      // NOTE 目标1:选中某一节点的同时，设置其对应的所有的“父级节点”和“子级节点”为选中状态；
      // NOTE 目标2:取消勾选某一节点，则设置其对应的所有的“子级节点”为未选中状态
      this.checkParentNodes(currNode);
      this.checkChildNodes(currNode, currNode.checked);

      if (checkKeys.length === 0) {
        this.$emit('select', []);
      } else {
        setTimeout(() => {
          checkKeys = this.$refs.elTree.getCheckedKeys();
          this.$emit('select', '当前选中' + checkKeys.length + '个节点');
          var tmp = [];
          checkKeys.forEach((key) => {
            this.list.forEach((obj) => {
              if (key === obj[this.defaultProps.value]) {
                tmp.push(obj);
              }
            });
          });

          this.$emit('change', tmp);
        }, 500);
      }
    },
    checkParentNodes: function (node) {
      if (node.parent.key) {
        if (!node.parent.checked) {
          this.$refs.elTree.setChecked(node.parent.key, true);
        }
        this.checkParentNodes(node.parent);
      }
    },
    checkChildNodes: function (node, flag) {
      // debugger
      const childNodes = node.childNodes;
      if (childNodes) {
        childNodes.forEach((item) => {
          this.$refs.elTree.setChecked(item.data.id, flag);
          this.checkChildNodes(item, flag);
        });
      }
    },
    getCheckedKeys() {
      return this.$refs.elTree.getCheckedKeys();
    },
  },
};
</script>

<style lang="less">
.customStyle .el-select-dropdown__wrap.el-scrollbar__wrap {
  min-height: 400px;
}
</style>
<style lang="less" scoped>
.customStyle {
  li {
    padding: 0;
    overflow: visible !important;
  }
  .el-select-dropdown__wrap.el-scrollbar__wrap {
    min-height: 400px;
  }
}
/deep/ .el-select {
  width: 100%;
}
</style>
